---
import type { HTMLAttributes } from 'astro/types';
import { transform } from 'ultrahtml';
import sanitize from 'ultrahtml/transformers/sanitize';
// These styles are included globally by default, but can be removed when `markdown.headingLinks` is
// set to `false`. We import them here to ensure they are included if the component is used with the
// global Markdown option disabled.
import '../style/anchor-links.css';
import { AstroError } from 'astro/errors';

const headingLevels = [1, 2, 3, 4, 5, 6, '1', '2', '3', '4', '5', '6'] as const;
interface Props extends HTMLAttributes<'h1'> {
	level: 1 | 2 | 3 | 4 | 5 | 6 | `${1 | 2 | 3 | 4 | 5 | 6}`;
	id: string;
}

const { level, id, ...attrs } = Astro.props;

if (!id) {
	throw new AstroError(
		'Missing `id` attribute passed to `<AnchorHeading>` component',
		`The \`<AnchorHeading>\` component requires an \`id\` attribute, but received \`${typeof id === 'string' ? '""' : id}\`.`
	);
}
if (!headingLevels.includes(level)) {
	throw new AstroError(
		'Invalid `level` attribute passed to `<AnchorHeading>` component',
		`The \`<AnchorHeading>\` component expects a \`level\` attribute of \`1 | 2 | 3 | 4 | 5 | 6\`, but received \`${level}\`.`
	);
}

const HeadingElement = `h${level}` as const;
const headingHTML = await Astro.slots.render('default');
const headingString = await transform(headingHTML, [sanitize({ unblockElements: [] })]);
const accessibleLabel = Astro.locals.t('heading.anchorLabel', {
	title: headingString,
	interpolation: { escapeValue: false },
})
---

{/* The spacing in this component is a little awkward to ensure whitespace matches what the rehype plugin produces. */}
<div class={`sl-heading-wrapper level-h${level}`}
	><HeadingElement {id} {...attrs} set:html={headingHTML} /><a class="sl-anchor-link" href={`#${id}`}
		><span aria-hidden="true" class="sl-anchor-icon"
			><svg width="16" height="16" viewBox="0 0 24 24"
				><path
					fill="currentcolor"
					d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"
				></path></svg
			></span
		><span class="sr-only" set:text={accessibleLabel} /></a
	></div
>
